package com.mechat.webview

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.webkit.WebSettings
import android.webkit.WebView
import com.custom.base.util.SDBase64
import com.mechat.js.AppJsHandler
import com.mechat.js.BaseJsHandler
import java.io.File

open class CustomWebView(context: Context, attrs: AttributeSet?) : WebView(context, attrs) {
    private var webViewClient: DefaultWebViewClient? = null
    private var webChromeClient: DefaultWebChromeClient? = null
    var cacheDir: File? = null
        private set
    var isImgSrcClick = false

    init {
        init()
    }

    fun setListenerWebViewClient(listener: WebViewClientListener?) {
        webViewClient?.setListener(listener, this@CustomWebView, isImgSrcClick)
    }

    fun setListenerWebChromeClient(listener: WebChromeClientListener?) {
        webChromeClient?.setListener(listener)
    }

    protected fun init() {
        val cacheDirPath =
            context.cacheDir.absolutePath + WEBVIEW_CACHE_DIR
        cacheDir = File(cacheDirPath)
        cacheDir?.apply {
            if (!exists()) {
                mkdirs()
            }
        }
        webViewClient = DefaultWebViewClient()
        webChromeClient = DefaultWebChromeClient()
        initSettings(settings)
        setWebViewClient(webViewClient!!)
        setWebChromeClient(webChromeClient)
        setDownloadListener { url, _, _, _, _ ->
            val uri = Uri.parse(url)
            val intent = Intent(Intent.ACTION_VIEW, uri)
            this@CustomWebView.context.startActivity(intent)
        }
        requestFocus()
    }

    @SuppressLint("SetJavaScriptEnabled", "SdCardPath","joinVIP")
    protected fun initSettings(settings: WebSettings) {
        setScaleToShowAll(true)
        setSupportZoom(true)
        setDisplayZoomControls(false)
        settings.defaultTextEncodingName = "utf-8"
        settings.javaScriptEnabled = true
        settings.allowFileAccess = true
        settings.javaScriptEnabled = true
        settings.domStorageEnabled = true // 开启DOM storage API 功能
        settings.cacheMode = WebSettings.LOAD_DEFAULT
        settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
        settings.savePassword = false
        settings.blockNetworkImage = false
        settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        settings.setGeolocationEnabled(true)
        cacheDir?.apply {
            settings.setGeolocationDatabasePath(absolutePath)
            settings.databasePath = absolutePath
//            settings.setAppCachePath(absolutePath)
        }

        // Database
        settings.databaseEnabled = true

        // AppCache
//        settings.setAppCacheEnabled(true)
//        settings.setAppCacheMaxSize(1024 * 1024 * 8.toLong())
//        var us = settings.userAgentString
//        us += " sdk_version_name/${SDPackageUtil.versionName} sdk_version/" + SDPackageUtil.versionCode + " sdk_guid/"+SDPackageUtil.deviceId + " screen_width/" + SDViewUtil.screenWidth + " screen_height/" + SDViewUtil.screenHeight+" type/android";
//        settings.userAgentString = us

        // 详情回调处理
        val detailHandler: AppJsHandler = object : AppJsHandler() {}
        addJavascriptInterface(detailHandler)
    }

    fun setScaleToShowAll(isScaleToShowAll: Boolean) {
        settings.loadWithOverviewMode = isScaleToShowAll
        settings.useWideViewPort = isScaleToShowAll
    }

    fun setSupportZoom(isSupportZoom: Boolean) {
        settings.setSupportZoom(isSupportZoom)
        settings.builtInZoomControls = isSupportZoom
    }

    fun setDisplayZoomControls(display: Boolean) {
        settings.displayZoomControls = display
    }

    @SuppressLint("JavascriptInterface")
    fun addJavascriptInterface(handler: BaseJsHandler?) {
        if (handler != null) {
            addJavascriptInterface(handler, handler.name)
        }
    }

    operator fun get(url: String?, mapHeader: Map<String?, String?>?) {
        get(url, null, mapHeader)
    }

    // get
    @JvmOverloads
    operator fun get(
        url: String?,
        params: RequestParams? = null,
        mapHeader: Map<String?, String?>? = null
    ) {
        var url = url
        if (TextUtils.isEmpty(url)) {
            return
        }
        if (params != null) {
            url = params.build(url!!)
        }
        url?.apply {
            if (mapHeader != null && mapHeader.isNotEmpty()) {
                loadUrl(url, mapHeader)
            } else {
                loadUrl(url)
            }
            Log.d("webview", url)
        }
    }

    // post
    @JvmOverloads
    fun post(url: String, params: RequestParams? = null) {
        if (TextUtils.isEmpty(url)) {
            return
        }
        var postData: ByteArray? = null
        if (params != null) {
            val data = params.build()
            data?.apply {
                if (!TextUtils.isEmpty(this)) {
                    postData = SDBase64.encodeToByte(this)
                }
            }
        }
        postUrl(url, postData!!)
    }

    fun loadJsFunction(function: String, vararg params: Any) {
        loadJsFunction(buildJsFunctionString(function, *params))
    }

    fun buildJsFunctionString(function: String, vararg params: Any): String {
        val sb = StringBuilder()
        if (!TextUtils.isEmpty(function)) {
            sb.append(function).append("(")
            if (params != null && params.isNotEmpty()) {
                for (param in params) {
                    if (param is String) {
                        sb.append("'").append(param.toString()).append("'")
                    } else {
                        sb.append(param.toString())
                    }
                    sb.append(",")
                }
                sb.setLength(sb.length - 1)
            }
            sb.append(")")
        }
        return sb.toString()
    }

    @SuppressLint("NewApi")
    fun loadJsFunction(js: String) {
        if (!TextUtils.isEmpty(js)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                evaluateJavascript(js) { }
            } else {
                loadUrl("javascript:$js")
            }
        }
    }

    companion object {
        private const val WEBVIEW_CACHE_DIR = "/webviewcache" // web缓存目录
    }
}